package com.kuaiditu.assistant.api.yd_api;

import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.kuaiditu.assistant.api.ParamsAnalog;
import com.kuaiditu.assistant.api.yd_api.entity.LoginRes;
import com.kuaiditu.assistant.entity.Operator;
import com.kuaiditu.assistant.module.retrofit.FastJsonConverterFactory;
import com.kuaiditu.assistant.module.retrofit.impl.YDConverterAdapter;
import com.kuaiditu.assistant.util.LogUtil;
import com.yunda.crypt.EDOutputData;
import com.yunda.crypt.NativeEncryption;
import com.yunda.crypt.PWDEncode;
import com.yunda.crypt.security.EncryptionFactory;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;


/**
 * Created by Eenie on 2017/8/24.
 * Email: eeniework@gmail.com
 * Des:
 */

public class YDApi {


    private YDService mYDService;
//    private AssistantApi assistantApi;
    private ParamsAnalog mParamsAnalog;

    private SimpleDateFormat mSimpleDateFormat;


    public YDApi(OkHttpClient client, ParamsAnalog paramsAnalog) {
        mSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        mParamsAnalog = paramsAnalog;
//        this.assistantApi = assistantApi;
        mYDService = new Retrofit.Builder()
                .baseUrl("http://bapp.yundasys.com:2059")
                .client(client)
                .addConverterFactory(FastJsonConverterFactory.create(new YDConverterAdapter()))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
                .create(YDService.class);
    }


//    public Observable<ResponseBody> fetchData(String data) {
//        RequestBody body = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), data);
//        return mYDService.ReqData(body);
//    }

    public Observable<YDBaseResponse> login(final String account, String pwd) {

//        String srcData = "{\"app\":\"bmapp\",\"appver\":\"5.6.0\",\"devsn\":\"858826136112855592\",\"mobile\":\"18918666766\",\"pass\":\"1cb62bce1791fd7c01e9a1bdd6240d2d\"}";

        Map<String, Object> data = new HashMap<>();
        data.put("app", "bmapp");
        data.put("appver", ParamsAnalog.YD_APP_VER);
        data.put("devsn", mParamsAnalog.getYd_devsn());
        data.put("mobile", account);
        data.put("pass", PWDEncode.toMD5(PWDEncode.SHA1(PWDEncode.toMD5(pwd))));
        StringBuffer param = new StringBuffer();

        param.append("sign_method=")
                .append("yd_md5")
                .append("&req_time=")
                .append(new Date().getTime())
                .append("&data=")
                .append(JSON.toJSONString(data))
                .append("&action=")
                .append("yundabm.account.loginsafe")
                .append("&appver=")
                .append(ParamsAnalog.YD_APP_VER)
                .append("&version=")
                .append("V2.5");

        String res = EncryptionFactory.getEncryption("yd_md5").encodeRequest(param.toString(), null, "UTF-8");
        RequestBody body = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), res);
        return mYDService.fetchData(body)
                .subscribeOn(Schedulers.io())
                .doOnNext(new Consumer<YDBaseResponse>() {
                    @Override
                    public void accept(YDBaseResponse response) throws Exception {
                        LoginRes loginRes = (LoginRes) response.getDeEntity(LoginRes.class);
                        mParamsAnalog.setYd_token(loginRes.getToken());
                        mParamsAnalog.setYd_public_key(loginRes.getPublicKey());
                        mParamsAnalog.setYDUserInfo(JSON.toJSONString(loginRes.getUserinfo()), account);
                        NativeEncryption.JNI_EDCodeInstance(ParamsAnalog.YD_HOST, ParamsAnalog.YD_PORT, mParamsAnalog.getYd_token(), ParamsAnalog.YD_APP_VER, mParamsAnalog.getYd_public_key());
                    }
                })
                .observeOn(AndroidSchedulers.mainThread());
    }


    public Observable<YDBaseResponse> addAcceptExpress(String express, Operator operator) {
        EDOutputData data = new EDOutputData();
        Map<String, Object> datas = new HashMap<>();
        List<String> rawData = new ArrayList<>();
        datas.put("datas", rawData);
        rawData.add(String.format("|%s|||||||||||||||||||||%s||||||||%s||%s||%s|%s|||",
                express,
                mParamsAnalog.getYDUserInfo().getCode(),
                operator.getYd_id(),
                mParamsAnalog.getYDUserInfo().getEmpid(),
                "24",
                mSimpleDateFormat.format(new Date())));


        Map<String, Object> h = new HashMap<>();
        h.put("company", mParamsAnalog.getYDUserInfo().getCode());
        h.put("dev1", mParamsAnalog.getYd_devsn());
        h.put("dev2", mParamsAnalog.getYDUserInfo().getAlipay());
        h.put("pass", mParamsAnalog.getYDUserInfo().getGunpass());
        h.put("user", mParamsAnalog.getYDUserInfo().getEmpid());
        h.put("ver", "2.0");
        datas.put("h", h);
        LogUtil.e(JSON.toJSONString(datas));
        NativeEncryption.JNI_IEncrypt(JSON.toJSONString(datas), data);
        StringBuffer param = new StringBuffer();
        param.append("sign_method=")
                .append("yd_md5")
                .append("&req_time=")
                .append(new Date().getTime())
                .append("&data=")
                .append(data.GetData())
                .append("&action=")
                .append("yundabm.biz.batchUploadScanInfo")
                .append("&appver=")
                .append("5.6.0")
                .append("&version=")
                .append("V2.5")
                .append("&token=")
                .append(mParamsAnalog.getYd_token());
        String res = EncryptionFactory.getEncryption("yd_md5").encodeRequest(param.toString(), null, "UTF-8");
        RequestBody body = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), res);
        return mYDService.fetchData(body).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<YDBaseResponse> addSignExpress(String express, Operator operator) {
        Map<String, Object> datas = new HashMap<>();
        List<String> rawData = new ArrayList<>();
        datas.put("datas", rawData);
        rawData.add(String.format("|%s||||||||||||%s|||||||%s||%s|||||||%s|%s||%s||%s|%s|||",
                express,
                "12",
                "1",
                mParamsAnalog.getYDUserInfo().getCode(),
                "本人",
                operator.getYd_id(),
                mParamsAnalog.getYDUserInfo().getEmpid(),
                "10",
                mSimpleDateFormat.format(new Date())));
        Map<String, Object> h = new HashMap<>();
        h.put("company", mParamsAnalog.getYDUserInfo().getCode());
        h.put("dev1", mParamsAnalog.getYd_devsn());
        h.put("dev2", operator.getAccout());
        h.put("pass", mParamsAnalog.getYDUserInfo().getGunpass());
        h.put("user", mParamsAnalog.getYDUserInfo().getEmpid());
        h.put("ver", "2.0");
        datas.put("h", h);
        LogUtil.e(JSON.toJSONString(datas));
        YDBaseRequest request = new YDBaseRequest("yundabm.biz.batchUploadScanInfo", datas, mParamsAnalog.getYd_token(), "V2.5", true);
        return mYDService.fetchData(request.getReqBody())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<YDBaseResponse> getUserList() {
//        {"h":{"company":"200040","dev1":"858826136112855592","dev2":"18918666766","pass":"e99a18c428cb38d5f260853678922e03","user":"9999","ver":"1.0"}}
        Map<String, Object> h = new HashMap<>();
        h.put("company", mParamsAnalog.getYDUserInfo().getCode());
        h.put("dev1", mParamsAnalog.getYd_devsn());
        h.put("dev2", mParamsAnalog.getYDUserInfo().getAlipay());
        h.put("pass", mParamsAnalog.getYDUserInfo().getGunpass());
        h.put("user", mParamsAnalog.getYDUserInfo().getEmpid());
        h.put("ver", "1.0");
        Map<String, Object> data = new HashMap<>();
        data.put("h", h);
        YDBaseRequest request = new YDBaseRequest("yundabm.cfg.getuserlist", data, mParamsAnalog.getYd_token(), "V2.5");

        return mYDService.fetchData(request.getReqBody());
    }


    public Observable<ResponseBody> fetchCom(String express) {
        return null;
    }


    public Observable<YDBaseResponse> fetchPicCode(String mobile) {

        Map<String, Object> param = new HashMap<>();
        param.put("app", "bmapp");
        param.put("mobile", mobile);
        final YDBaseRequest request = new YDBaseRequest("yundabm.account.getpic", param, "", "V2.5", false);

        if (TextUtils.isEmpty(mParamsAnalog.getYd_devsn())) {
            return fetchDevsn(mobile)
                    .flatMap(new Function<YDBaseResponse, ObservableSource<YDBaseResponse>>() {
                        @Override
                        public ObservableSource<YDBaseResponse> apply(@NonNull YDBaseResponse responseBody) throws Exception {
                            String devsn = responseBody.getDeEntity().getJSONObject("res").getString("devsn");
                            mParamsAnalog.setYd_devsn(devsn);
                            return mYDService.fetchData(request.getReqBody());
                        }
                    });

        } else {
            return mYDService.fetchData(request.getReqBody());
        }
    }


    public Observable<YDBaseResponse> bindDevice(String mobile, String smsCode) {
//                 sign_method=yd_md5
//                &req_time=1504055969397
//                &data={"app":"bmapp","company":"200040","devsn":"868524107104813872","mobile":"18918666766","smscode":"694975","user":"9999"}
//                &action=yundabm.account.binddevice
//                &appver=5.6.0
//                &version=V2.5
//                &token=CFHDgaBY9i-Y0b18c7Y63B2V
//                &sign=CAE80A0F75E93989EEE688093E5ACA47

        YDUserInfo userInfo = mParamsAnalog.getYDUserInfo();
        Map<String, Object> param = new HashMap<>();
        param.put("app", "bmapp");
        param.put("company", userInfo.getCode());
        param.put("devsn", mParamsAnalog.getYd_devsn());
        param.put("mobile", mobile);
        param.put("smscode", smsCode);
        param.put("user", userInfo.getEmpid());

        YDBaseRequest request = new YDBaseRequest("yundabm.account.binddevice", param, mParamsAnalog.getYd_token(), "V2.5", true);
        return mYDService.fetchData(request.getReqBody());
    }


    public Observable<YDBaseResponse> fetchSmsCode(String mobile, String picCode) {
        Map<String, Object> param = new HashMap<>();
        param.put("app", "bmapp");
        param.put("mobile", mobile);
        param.put("code", picCode);
        param.put("type", "sms");
        YDBaseRequest request = new YDBaseRequest("yundabm.account.getverifycode", param, mParamsAnalog.getYd_token(), "V2.5", false);
        return mYDService.fetchData(request.getReqBody());
    }

    public Observable<YDBaseResponse> fetchDevsn(String mobile) {
        Map<String, Object> param = new HashMap<>();
        param.put("app", "bmapp");
        param.put("mobile", mobile);
        param.put("type", "android");
        YDBaseRequest request = new YDBaseRequest("yundabm.account.getdevice", param, mParamsAnalog.getYd_token(), "V2.5", true);
        return mYDService.fetchData(request.getReqBody());
    }
}
